package cn.itcast.nems.base.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.itcast.ic.common.bean.Page;
import cn.itcast.ic.common.exception.BizException;
import cn.itcast.ic.common.exception.v2.BizExceptionProducer;
import cn.itcast.nems.base.api.SchoolApi;
import cn.itcast.nems.base.dao.entity.ResponsibilityCampus;
import cn.itcast.nems.base.dao.entity.ResponsibilityCampusDetail;
import cn.itcast.nems.base.dao.mapper.ResponsibilityCampusMapper;
import cn.itcast.nems.base.dto.SchoolDTO;
import cn.itcast.nems.base.service.ResponsibilityCampusDetailService;
import cn.itcast.nems.base.service.ResponsibilityCampusService;
import cn.itcast.nems.common.account.AccountHolder;
import cn.itcast.nems.common.bean.State;
import cn.itcast.nems.common.enumeration.CustomBizError;
import cn.itcast.nems.employee.dao.entity.Employee;
import cn.itcast.nems.employee.dto.EmployeeInfoDto;
import cn.itcast.nems.employee.service.EmployeeGroupService;
import cn.itcast.nems.employee.service.EmployeeService;
import cn.itcast.nems.studentrecord.enumeration.StudentRecordErrorBodyEnum;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * <p>
 * 员工归属负责校区;注：通常为出纳负责 服务实现类
 * </p>
 *
 * @author czq
 * @since 2024-02-28
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ResponsibilityCampusServiceImpl extends ServiceImpl<ResponsibilityCampusMapper, ResponsibilityCampus> implements ResponsibilityCampusService {
    private final EmployeeService employeeService;
    private final ResponsibilityCampusDetailService responsibilityCampusDetailService;
    private final SchoolApi schoolApi;
    private final EmployeeGroupService employeeGroupService;

    @Override
    public Page<ResponsibilityCampus> listPage(Integer pageNumber, Integer pageSize, ResponsibilityCampus params) {
        IPage<ResponsibilityCampus> pageData = baseMapper.listPage(new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(pageNumber, pageSize), params);
        if (CollectionUtil.isEmpty(pageData.getRecords())) {
            return Page.of(pageNumber, pageSize, 0, null);
        }
        pageData.getRecords().stream()
                .map(item -> {
                    item.setEmployeeName(item.getEmployeeName() + "（" + item.getEmployeeEmail() + "）");
                    String modifiedBy = item.getModifiedBy();
                    Employee employeeModified = employeeService.findOneByEmail(modifiedBy);
                    item.setModifiedName(Objects.nonNull(employeeModified) ? employeeModified.getName() : modifiedBy);
                    item.setModifiedByName(Objects.nonNull(employeeModified) ? employeeModified.getName() + "（" + employeeModified.getEmail() + "）" : modifiedBy);
                    List<ResponsibilityCampusDetail> responsibilityCampusDetails = responsibilityCampusDetailService.employeeCampusList(item.getId(), item.getDefaultCampusId());
                    item.setEmployeeCampuss(responsibilityCampusDetails.stream().map(ResponsibilityCampusDetail::getCampusName).collect(Collectors.toList()));
                    return item;
                })
                .toList();
        return Page.of(pageNumber, pageSize, (int) pageData.getTotal(), pageData.getRecords());
    }

    @Override
    public ResponsibilityCampus getById(String id) {
        ResponsibilityCampus responsibilityCampus = baseMapper.selectById(id);
        List<ResponsibilityCampusDetail> responsibilityCampusDetails = responsibilityCampusDetailService.employeeCampusList(id, responsibilityCampus.getDefaultCampusId());
        responsibilityCampus.setEmployeeCampuss(responsibilityCampusDetails.stream().map(ResponsibilityCampusDetail::getCampusId).collect(Collectors.toList()));
        return responsibilityCampus;
    }

    @Override
    @Transactional
    public String create(ResponsibilityCampus params) {
        String employeeEmail = params.getEmployeeEmail();
        String defaultCampusId = params.getDefaultCampusId();
        Boolean exists = exists(params.getId(), employeeEmail);
        Assert.isTrue(!exists, BizExceptionProducer.produce(StudentRecordErrorBodyEnum.BAD_REQUEST, "出纳已存在"));
        // 获取校区名称
        SchoolDTO schoolDTO = schoolApi.findById(defaultCampusId);
        params.setDefaultCampusName(schoolDTO.getName());
        // 获取出纳姓名和工号
        Employee employeeModified = employeeService.findOneByEmail(employeeEmail);
        if (employeeModified != null) {
            params.setEmployeeName(employeeModified.getName());
            params.setEmployeeJobNumber(employeeModified.getJobNumber());
        }else {
            EmployeeInfoDto employeeInfoDto = employeeGroupService.employeeAccountInfo(employeeEmail);
            if (employeeInfoDto != null) {
                params.setEmployeeName(employeeInfoDto.getName());
                params.setEmployeeJobNumber(employeeInfoDto.getJobNumber());
            }
        }
        // 获取用户邮箱
        String email = AccountHolder.getRequiredAccount();
        params.setCreatedBy(email);
        params.setModifiedBy(email);
        params.setId(UUID.randomUUID().toString().replace("-", ""));
        params.setState(State.ENABLE.name());
        int insert = baseMapper.insert(params);
        cn.hutool.core.lang.Assert.isTrue(insert > 0, BizExceptionProducer.produce(StudentRecordErrorBodyEnum.BAD_REQUEST, "创建失败"));
        String id = params.getId();
        // 添加责任校区
        params.getEmployeeCampuss().forEach(i -> responsibilityCampusDetailService.create(id, i));
        return id;
    }

    @Override
    public Boolean delete(String id) {
        ResponsibilityCampus responsibilityCampus = baseMapper.selectById(id);
        cn.hutool.core.lang.Assert.notNull(responsibilityCampus, BizExceptionProducer.produce(StudentRecordErrorBodyEnum.BAD_REQUEST, "数据不存在"));
        return lambdaUpdate().eq(ResponsibilityCampus::getId, id)
                .set(ResponsibilityCampus::getDeletedBy, AccountHolder.getRequiredAccount())
                .set(ResponsibilityCampus::getDeletedDatetime, LocalDateTime.now())
                .set(ResponsibilityCampus::getDeletedFlag, !responsibilityCampus.getDeletedFlag()).update();
    }

    @Override
    public Boolean delete(String id, String state) {
        return lambdaUpdate().eq(ResponsibilityCampus::getId, id)
                .set(ResponsibilityCampus::getDeletedBy, AccountHolder.getRequiredAccount())
                .set(ResponsibilityCampus::getDeletedDatetime, LocalDateTime.now())
                .set(ResponsibilityCampus::getState, state).update();
    }

    @Override
    @Transactional
    public Boolean update(ResponsibilityCampus params) {
        String id = params.getId();
        cn.hutool.core.lang.Assert.notNull(id, () -> new BizException(CustomBizError.message(CustomBizError.PARAM_EMPTY, "id不能为空")));
        String employeeEmail = params.getEmployeeEmail();
        String defaultCampusId = params.getDefaultCampusId();
        Boolean exists = exists(params.getId(), employeeEmail);
        Assert.isTrue(!exists, BizExceptionProducer.produce(StudentRecordErrorBodyEnum.BAD_REQUEST, "出纳已存在"));
        // 获取默认校区名称
        SchoolDTO schoolDTO = schoolApi.findById(defaultCampusId);
        params.setDefaultCampusName(schoolDTO.getName());
        // 获取出纳姓名和工号
        Employee employeeModified = employeeService.findOneByEmail(employeeEmail);
        params.setEmployeeName(employeeModified.getName());
        params.setEmployeeJobNumber(employeeModified.getJobNumber());
        // 获取用户邮箱
        String email = AccountHolder.getRequiredAccount();
        params.setCreatedBy(email);
        params.setModifiedBy(email);
        int updateById = baseMapper.updateById(params);
        cn.hutool.core.lang.Assert.isTrue(updateById > 0, BizExceptionProducer.produce(StudentRecordErrorBodyEnum.BAD_REQUEST, "编辑失败"));
        // 删除责任校区
        responsibilityCampusDetailService.deleteByResponsibilityCampusId(id);
        // 添加责任校区
        params.getEmployeeCampuss().forEach(i -> responsibilityCampusDetailService.create(id, i));
        return Boolean.TRUE;
    }

    @Override
    public List<ResponsibilityCampus> defaultCampusList(String defaultCampusName) {
        return lambdaQuery()
                .eq(ResponsibilityCampus::getState, State.ENABLE.name())
                .eq(ResponsibilityCampus::getDeletedFlag, Boolean.FALSE)
                .like(ResponsibilityCampus::getDefaultCampusName, defaultCampusName)
                .groupBy(ResponsibilityCampus::getDefaultCampusId).list();
    }

    @Override
    public ResponsibilityCampus getResponsibilityCampusIdsByEmployeeEmail(String requiredAccount) {
        return lambdaQuery()
                .eq(ResponsibilityCampus::getState, State.ENABLE.name())
                .eq(ResponsibilityCampus::getDeletedFlag, Boolean.FALSE)
                .like(ResponsibilityCampus::getEmployeeEmail, requiredAccount).one();
    }

    @Override
    public Boolean exists(String id, String employeeEmail) {
        return lambdaQuery()
                .eq(ResponsibilityCampus::getEmployeeEmail, employeeEmail)
                // 过滤掉修改本身
                .ne(StringUtils.hasText(id), ResponsibilityCampus::getId, id)
                .exists();
    }
}
